package com.scu.qingshi.facade.domain.impl;

import com.scu.qingshi.common.enums.ResponseCodeEnum;
import com.scu.qingshi.common.exception.authorization.AuthorizationException;
import com.scu.qingshi.common.response.BaseResponse;
import com.scu.qingshi.config.cummunity.CommunityConfig;
import com.scu.qingshi.config.cummunity.CommunityFactory;
import com.scu.qingshi.domain.authorize.model.AuthorizationEmailMessage;
import com.scu.qingshi.domain.authorize.param.LoginRequest;
import com.scu.qingshi.domain.authorize.param.RegistrationRequest;
import com.scu.qingshi.domain.authorize.response.AuthorizeResponse;
import com.scu.qingshi.domain.authorize.service.AuthorizeService;
import com.scu.qingshi.domain.email.service.VerifyCodeService;
import com.scu.qingshi.facade.domain.NetworkAuthorizationFacade;
import com.scu.qingshi.infrastructure.dao.po.User;
import com.scu.qingshi.infrastructure.dao.service.UserService;
import com.scu.qingshi.infrastructure.utils.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author qingshi
 */
@Api(tags = "网络授权")
@RequestMapping("/internet")
@RestController
public class NetworkAuthorizationFacadeImpl implements NetworkAuthorizationFacade {

    private final Logger logger = LogManager.getLogger(this.getClass());

    @Resource
    RedisUtil redisUtil;

    @Resource
    UserService userService;

    @Resource
    AuthorizeService authorizeService;

    @Resource
    VerifyCodeService verifyCodeService;

    @ApiOperation("登录")
    @Override
    @PostMapping("/login")
    public BaseResponse login(LoginRequest request) throws Exception {

        logger.info("login request = {}",request.toString());
        final Integer FAIL = null;
        AuthorizeResponse res = new AuthorizeResponse();
        User result = authorizeService.login(request);
        if (result.equals(FAIL)){
            logger.info("login fail, email = {}",request.getEmail());
            res.setCode(ResponseCodeEnum.AUTHORITY_ERROR.name());
            res.setMsg("登陆失败，请检查账号密码");
            res.setSuccess(false);
            res.setUser(result);
        }else {
            logger.info("login success, email = {}",request.getEmail());
            res.setSuccess(true);
            res.setMsg("登陆成功");
            res.setCode(ResponseCodeEnum.SUCCESS.name());
            res.setUser(result);
        }

        return res;
    }

    @ApiOperation("注册")
    @PostMapping("/register")
    @Override
    public BaseResponse register(RegistrationRequest request) throws Exception {

        AuthorizeResponse res = new AuthorizeResponse();

        // 判断验证码
        if (!Objects.equals(
                redisUtil.getObject(AuthorizationEmailMessage.getRedisKey(request.getEmail())),
                request.getVerifyCode())) {
            throw AuthorizationException.errorVerifyCodeException("注册验证码错误");
        }

        if (userService.userIsExitByEmail(request.getEmail())){
            throw AuthorizationException.duplicateRegisterException("邮箱已注册");
        }

        res.setUser(authorizeService.register(request));
        res.setMsg("注册成功");
        res.setCode(ResponseCodeEnum.SUCCESS.name());
        res.setSuccess(Boolean.TRUE);
        return res;
    }

    @ApiOperation("获取邮箱验证码")
    @GetMapping("/getCodeByEmail")
    @Override
    public BaseResponse getVerifyCode(String email) throws Exception{

        // 检测邮箱是否已注册
        if (userService.userIsExitByEmail(email)){
            throw new Exception("邮箱已注册");
        }

        String emailKey = AuthorizationEmailMessage.getRedisKey(email);

        if (Objects.nonNull(redisUtil.getObject(emailKey))){
            throw new Exception("验证码已发送，请稍后再获取");
        }

        String code = verifyCodeService.sendVerifyCode(email);

        redisUtil.setObjectExpire(emailKey,code, AuthorizationEmailMessage.EXPIRE_TIME, TimeUnit.MINUTES);

        BaseResponse res = new BaseResponse();
        res.setCode(ResponseCodeEnum.SUCCESS.name());
        res.setSuccess(true);
        res.setMsg("发送成功，请查收");
        return res;
    }

    @GetMapping("/getUser")
    @ApiOperation("获取用户信息")
    @Override
    public BaseResponse getUser(Integer userId) {
        AuthorizeResponse res = new AuthorizeResponse();

        res.setUser(userService.getById(userId));
        res.setMsg("查询用户成功");
        res.setCode(ResponseCodeEnum.SUCCESS.name());
        res.setSuccess(Boolean.TRUE);
        return res;
    }

    @ApiOperation("社团登陆")
    @PostMapping("/communityLogin")
    @Override
    public BaseResponse communityLogin(String openId, String password) throws AuthorizationException {
        logger.info("社团openId={}",openId);

        CommunityConfig community = CommunityFactory.getCommunity(openId);
        if (Objects.isNull(community)){
            throw AuthorizationException.dataException("社团openId不存在");
        }
        if (!Objects.equals(community.getPassword(),password)){
            throw AuthorizationException.dataException("社团密码错误");
        }

        BaseResponse res = new BaseResponse();
        res.setSuccess(true);
        res.setMsg("登陆成功");
        res.setCode(ResponseCodeEnum.SUCCESS.name());

        return res;
    }

}
